﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using YJKRGeometry;
using QuickModel.QuickModelFrame;

namespace QuickModel.TransformWall
{
	[Rebuilder(RebuilderName = "WallRebuilder")]
	public class WallRebuilder : IRevitModelRebuilder
	{
		public bool TryRebuildRevitModel(Autodesk.Revit.DB.Document inputDoc, RevitModelRequest inputReqeust, out BuildData buildData)
		{
			buildData = new BuildData();
			WallRevitModelRequest wallRevitModelRequest = inputReqeust as WallRevitModelRequest;
			bool flag = wallRevitModelRequest == null;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				try
				{
					WallRequest request = wallRevitModelRequest.Request;
					bool flag2 = this.HasCreateWall(inputDoc, request);
					if (flag2)
					{
						return false;
					}
					Level genLevel = inputDoc.ActiveView.GenLevel;
					Level upLevel = this.GetUpLevel(inputDoc, genLevel);
					double num = AssistFunc.mmToFeet(3000.0);
					bool flag3 = upLevel != null;
					if (flag3)
					{
						num = upLevel.Elevation - genLevel.Elevation;
					}
					Wall wall = Wall.Create(inputDoc, request.LocationCurve, request.WallTypeId, genLevel.Id, num, 0.0, false, request.IsStruct);
					bool flag4 = upLevel != null;
					if (flag4)
					{
						Parameter parameter = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE);
						parameter.Set(upLevel.Id);
					}
					bool flag5 = !Geometry.IsEqual(request.TopOffset, 0.0);
					if (flag5)
					{
						Parameter parameter2 = wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET);
						parameter2.Set(request.TopOffset);
					}
				}
				catch
				{
					return false;
				}
				result = true;
			}
			return result;
		}

		private Level GetUpLevel(Autodesk.Revit.DB.Document inputDoc, Level bottomLevel)
		{
			bool flag = this.m_lstAllLevel == null;
			if (flag)
			{
				this.m_lstAllLevel = this.GetSortLevels(inputDoc);
			}
			Level result = null;
			foreach (Level level in this.m_lstAllLevel)
			{
				bool flag2 = level.Elevation > bottomLevel.Elevation;
				if (flag2)
				{
					result = level;
					break;
				}
			}
			return result;
		}

		private List<Level> GetSortLevels(Autodesk.Revit.DB.Document inputDoc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(inputDoc);
			List<Level> list = (from l in filteredElementCollector.OfClass(typeof(Level))
			select l as Level).ToList<Level>();
			list.Sort((Level l1, Level l2) => l1.Elevation.CompareTo(l2.Elevation));
			return list;
		}

		private bool HasCreateWall(Autodesk.Revit.DB.Document doc, WallRequest wq)
		{
			Curve locationCurve = wq.LocationCurve;
			XYZ endPoint = locationCurve.GetEndPoint(0);
			XYZ endPoint2 = locationCurve.GetEndPoint(1);
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc, doc.ActiveView.Id);
			List<Element> list = filteredElementCollector.OfCategory(BuiltInCategory.OST_Walls).ToList<Element>();
			foreach (Element element in list)
			{
				Wall wall = element as Wall;
				bool flag = wall != null;
				if (flag)
				{
					LocationCurve locationCurve2 = wall.Location as LocationCurve;
					Curve curve = locationCurve2.Curve;
					XYZ endPoint3 = curve.GetEndPoint(0);
					XYZ endPoint4 = curve.GetEndPoint(1);
					bool flag2 = (Geometry.IsEqual(endPoint, endPoint3) && Geometry.IsEqual(endPoint2, endPoint4)) || (Geometry.IsEqual(endPoint, endPoint4) && Geometry.IsEqual(endPoint2, endPoint3));
					if (flag2)
					{
						return true;
					}
				}
			}
			return false;
		}

		private List<Level> m_lstAllLevel = null;
	}
}
